/*
 * Copyright (C) 2010 第2回 SHARPハッカソン＠東広島
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.hackathon.bp.hayaben;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;

import com.felicanetworks.mfc.Felica;
import com.felicanetworks.mfc.FelicaEventListener;
import com.felicanetworks.mfc.FelicaException;

/**
 * LIFE CYCLE with method<br>
 * connectAndActivate->bindService->onServiceConnected->activateFelica->ANY_OPERATIONS->disconnectAndInactivate->unbindService->onServiceDisconnected->inactivateFelica
 * @author 共有コミュニケーションチーム (adamrocker, BaoBab, tarotaro)
 * 
 * FelicaServiceは、Felica Hackathonの成果物を利用しています。 @第2回 SHARPハッカソン＠東広島
 */
public class FelicaService implements ServiceConnection {

    private final static FelicaService sInstance = new FelicaService();
    private boolean mConnected = false;
    private static Felica sFelica;
    private Context mContext;
    private FelicaEventListener mListener;

    private FelicaService() {}

    public static FelicaService getInstance() {
        return sInstance;
    }

    /*
     * return nullが入るかもしれないので注意
     */
    public static Felica getFelica() {
        return sFelica;
    }

    
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.i("hoge","FelicaService#onServiceConnected");
        sFelica = ((Felica.LocalBinder) service).getInstance();
        mConnected = true;
        activateFelica();
    }

    
    public void onServiceDisconnected(ComponentName name) {
        Log.i("hoge","FelicaService#onServiceDisconnected");
        if (sFelica != null) {
            try {
                sFelica.inactivateFelica();
            } catch (FelicaException e) {
                e.printStackTrace();
            }
        }

        sFelica = null;
        mConnected = false;
    }

    public void setContext(Context context, FelicaEventListener listener) {
        mContext = context;
        mListener = listener;
    }

    private void activateFelica() {
        Log.i("hoge","activate");
        try {
            sFelica.inactivateFelica();//とりあずinactivateやっとく
            sFelica.activateFelica(null, mListener);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (FelicaException e) {
            e.printStackTrace();
            mListener.errorOccurred(0, "ERROR ACTIVATE", null);//ここの処理はFelicaEventListenerでやってくれないと第3引数をどうしたら…
        }
    }

    public void connectAndActivate() throws Exception {
        Log.i("hoge","FelicaService#connect");
        if (mContext == null) {
            Log.e("hoge","Context is not set");
            throw new Exception("connect error:Context is not set.");
        }

        if (mConnected) {
            Log.d("hoge","Already be connected");
            activateFelica();
            return;
        }

        Intent intent = new Intent();
        intent.setClass(mContext, Felica.class);
        //serviceにconnectできたらonServiceConnectedメソッドが呼び出されるので、そこでactivateする。
        if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
            Log.e("hoge","bind error:Context#bindService() failed.");
            throw new Exception("bind error:Context#bindService() failed.");
        }
    }

    public void disconnectAndInactivate() throws Exception {
        Log.i("hoge","FelicaService#disconnect");

        if (mContext == null) {
            throw new Exception("connect error:Context is not set.");
        }

        if (!mConnected) {
            return;
        }

        mContext.unbindService(this);
    }
}